package com.ejlchina.common.message;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.alibaba.fastjson.JSONObject;
import com.ejlchina.common.util.StringUtils;

/**
 * 聚合信息发送器
 * 
 * @author Troy.Zhou
 * 
 * @since 1.0.2
 * 
 */
public class JuheMsgSender implements MsgSender {

	static Logger log = LoggerFactory.getLogger(JuheMsgSender.class);
	
	public static String JU_HE_URL = "http://v.juhe.cn/sms/send";

	private String appId;
	private MsgTemplate[] templates;
	
	
	@Override
	public boolean send(String phone, String tmplName, String... tmplArgs) {
		MsgTemplate template = getMsgTemplate(tmplName);
		if (template == null) {
			throw new RuntimeException("No such MsgTemplate named: " + tmplName);
		}
		Map<String, String> params = new HashMap<String, String>();
		params.put("mobile", phone);
		params.put("tpl_id", template.getTmplId());
		params.put("key", appId);
		if (tmplArgs != null) {
			String[] argNames = template.getTmplArgs();
			if (tmplArgs.length > 0 && (argNames == null || argNames.length < tmplArgs.length)) {
				throw new RuntimeException("MsgTemplate tmplArgs not match: " + Arrays.toString(argNames) + " to " + Arrays.toString(tmplArgs));
			}
			StringBuilder sb = new StringBuilder();
			for (int index = 0; index < tmplArgs.length; index ++) {
				sb.append("#").append(argNames[index]).append("#=").append(tmplArgs[index]);
				if (index < tmplArgs.length - 1) {
					sb.append("&");
				}
			}
			try {
				params.put("tpl_value", java.net.URLEncoder.encode(sb.toString(), "utf-8"));
			} catch (UnsupportedEncodingException e) {
				throw new RuntimeException(e);
			}
		}
		params.put("dtype", "json");
		try {
			return send(phone, params);
		} catch (Exception e) {
			throw new RuntimeException("聚合信息发送异常：", e);
		}
	}

	private boolean send(String phone, Map<String, String> params) throws Exception {
		
		log.info("send params [" + phone + "] = " + params);
		
		List<NameValuePair> list = new ArrayList<>();
		for (Entry<String, String> entry: params.entrySet()) {
			list.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
		}
		
		HttpEntity entity = new UrlEncodedFormEntity(list, "utf-8");
		
		HttpPost post = new HttpPost(JU_HE_URL) ; 
		post.setEntity(entity);
		
		HttpClient client = HttpClientBuilder.create().build();
		HttpResponse response = client.execute(post);
		
		int statusCode = response.getStatusLine().getStatusCode();
		if (statusCode != HttpStatus.SC_OK) {
			log.error("聚合短信返回状态码不是200：" + statusCode);
			return false;
		}
		
		String result = EntityUtils.toString(response.getEntity());
		
		log.info("send result [" + phone + "] = " + result);
		
		if (StringUtils.notBlank(result)) {
			JSONObject json = JSONObject.parseObject(result);
			if (json.getString("error_code").equals("0")) {
				return true;
			} else {
				log.error("发送信息不成功： " + result);
				return false;
			}
		} else {
			log.error("发送信息返回内容为空！ ");
			return false;
		}
	}

	private MsgTemplate getMsgTemplate(String tmplName) {
		if (tmplName != null && templates != null) {
			for (MsgTemplate template: templates) {
				if (tmplName.equals(template.getName())) {
					return template;
				}
			}
		}
		return null;
	}
	
	public void setAppId(String appId) {
		this.appId = appId;
	}

	public void setTemplates(MsgTemplate[] templates) {
		this.templates = templates;
	}
	
}
